package com.david.core.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

/**
 * todo: 1.添加背景图片自定义，2.添加属性动态获取，3.ondraw及onTouchEvent中计算值优化
 */
class VerticalSeekbar:View {
    private val paint = Paint()

    private var verticalPadding = 10

    private var circleCenterY = 50f
    private var circleRadius = 10f
    private var circleColor = Color.GREEN

    private var lineWidth = 10

    private var onVBProgressChangeListener: OnVBProgressChangeListener? = null

    init {
        paint.color = Color.GRAY
    }

    constructor(context: Context):super(context)
    constructor(context: Context, attr: AttributeSet):super(context, attr)

    //以空间换时间，避免每次都计算
    private var startX = 0f//竖线开始的x坐标
    private var endX = 0f//竖线结束的x坐标
    private var startY = 0f
    private var endY = 0f

    private var circleCenterX = 0f

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.GRAY
        canvas.drawRoundRect(startX, startY, endX, endY, 10f, 10f, paint)


        paint.color = circleColor
        canvas.drawCircle(circleCenterX, circleCenterY, circleRadius, paint)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (startX == 0f) {
            startX = ((measuredWidth shr 1) - (lineWidth shr 1)).toFloat()//竖线开始的x坐标
            endX = ((measuredWidth shr 1) + (lineWidth shr 1)).toFloat()//竖线结束的x坐标
            startY = verticalPadding.toFloat()
            endY = measuredHeight.toFloat() - verticalPadding

            circleCenterX = (measuredWidth shr 1).toFloat()

            lineHeight = (measuredHeight - (verticalPadding shl 1)).toFloat()
        }
    }

    private var isDragged = false
    private var isExecuteLessOrMore = false//大于最大值／小于0时是否已经执行过回调，设置回调只执行一次
    private var lineHeight = 0f

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event != null) {
            when(event.action){
                MotionEvent.ACTION_DOWN -> {
                    isDragged = true

                    when {
                        event.y <= verticalPadding -> {
                            onVBProgressChangeListener?.onTouchDown(0)
                            isExecuteLessOrMore = true
                            return true
                        }
                        event.y > (measuredHeight - verticalPadding) -> {
                            onVBProgressChangeListener?.onTouchDown(100)
                            isExecuteLessOrMore = true
                            return true
                        }
                        else -> {
                            circleCenterY = event.y
                            onVBProgressChangeListener?.onTouchDown((((circleCenterY - verticalPadding)/lineHeight)*100).toInt())
                        }
                    }
                }
                MotionEvent.ACTION_MOVE -> {
                    when {
                        event.y <= verticalPadding -> {
                            if (!isExecuteLessOrMore) {
                                circleCenterY = verticalPadding.toFloat()
                                onVBProgressChangeListener?.onTouchDown(0)
                                isExecuteLessOrMore = true
                                invalidate()

//                                Log.e("num", "progress is :" + (((circleCenterY - verticalPadding) / lineHeight) * 100).toInt())
                            }
                            return true
                        }
                        event.y >= (measuredHeight - verticalPadding) -> {
                            if (!isExecuteLessOrMore) {
                                circleCenterY = (measuredHeight - verticalPadding).toFloat()
                                onVBProgressChangeListener?.onTouchDown(100)
                                isExecuteLessOrMore = true
                                invalidate()
//                                Log.e("num", "progress is :" + (((circleCenterY - verticalPadding) / lineHeight) * 100).toInt())
                            }

                            return true
                        }
                        else -> {

                            circleCenterY = event.y

                            invalidate()

                            onVBProgressChangeListener?.onDrag((((circleCenterY - verticalPadding) / lineHeight) * 100).toInt())
//                            Log.e("num", "progress is :" + (((circleCenterY - verticalPadding) / lineHeight) * 100).toInt())

                            isExecuteLessOrMore = false
                        }
                    }
                }
                MotionEvent.ACTION_CANCEL,MotionEvent.ACTION_UP -> {
                    when {
                        event.y <= verticalPadding -> {
                            circleCenterY = verticalPadding.toFloat()

                            onVBProgressChangeListener?.onTouchUp(0)
                            return true
                        }
                        event.y > (measuredHeight - verticalPadding) -> {
                            circleCenterY = (measuredHeight - verticalPadding).toFloat()

                            onVBProgressChangeListener?.onTouchUp(100)
                            return true
                        }
                        else -> {
                            circleCenterY = event.y
                            onVBProgressChangeListener?.onTouchUp((((circleCenterY - verticalPadding)/lineHeight)*100).toInt())
                        }
                    }

                    isDragged = false
                    isExecuteLessOrMore = false
                }
            }
        }
        return true
    }
}

/**
 * VerticalBar
 */
interface OnVBProgressChangeListener{
    open fun onTouchDown(progress:Int)
    open fun onDrag(progress:Int)
    open fun onTouchUp(progress:Int)
}